import java.io.*;
import java.lang.*;
import java.util.*;
import org.apache.commons.collections.*;

public class ParseGdf 
{
	private int bypassSlashNum = -1;
	HashMap<String, String> obj2DirMap = null;
	
	ParseGdf(int bypassSlashNum)
	{
		this.bypassSlashNum = bypassSlashNum;
	}
	
	ParseGdf()
	{
		
	}
	
	void getObj2ProjMap(String proj2PathMapFile, String gdfFile, 
			String localObj2ProjMapFile, String obj2ObjMapFile) 
		throws IOException
	{
		HashMap<String, String> path2ProjMap = new HashMap<String, String>();
		//read in the proj-path map
		Utilities.readMapFromFile(path2ProjMap, proj2PathMapFile);
		//get proj set
		Set<String> projPathSet = path2ProjMap.keySet();
		
		//build a path-proj tree
		Utilities uti = new Utilities();
		for (String projPath: projPathSet)
		{	
			uti.insertTree(projPath, path2ProjMap.get(projPath));
		}
		
		//HashMap<String, String> localObj2DirMap = new HashMap<String, String>();
		
		HashMap<String, String> localObj2ProjMap = new HashMap<String, String>();
		
		//HashSet<String> concernSet = new HashSet<String>();
		 
		FileInputStream fstream = new FileInputStream(gdfFile);
		DataInputStream inStream = new DataInputStream(fstream);
		BufferedReader inBuffer = new BufferedReader(new InputStreamReader(inStream));
	  
		String line = null;
		//bypass the node-def header
	  	line = inBuffer.readLine();
	  
	  	//int tt = 0;
	  	//int ss = 0;
	  	
	  	MultiHashMap extensionSet = new MultiHashMap();
	  	
	  	while((line = inBuffer.readLine()) != null)
	  	{
	  		
	  		String words[] = line.split(",");
	  		
		 
	  		//get out of the loop when going into the edge-def region
	  		if (words[0].equals("edgedef> node1"))
	  		{
	  			break;
	  		}
	  		
	  		//get the dir
	  		
	  		String dir = null;
	  		if (bypassSlashNum == -1)
	  		{
	  			dir = Utilities.getPath(words[1].trim());
	  		}
	  		else
	  		{
	  			dir = Utilities.truncat(bypassSlashNum, words[9].trim());
	  		}
	  		
	  		if (dir == null)
	  		{
	  			//localObj2ProjMap.put(words[0].trim(), "main");
	  			
	  			continue;
	  		}
	  		
	  		//add the local obj to map
	  		//if (projPathSet.contains(dir))
	  		String projName = null;
			if ((projName = uti.queryTree(dir)) != null)
	  		{
	  			String objName = words[0].trim();
	  			
	  			/*
	  			int indexOfUnderscore = objName.indexOf('_');
	  			indexOfUnderscore = indexOfUnderscore < 0 ? objName.length() : indexOfUnderscore;
	  			
	  			objName = objName.substring(0, indexOfUnderscore);
				
				localObj2ProjMap.put(objName, projName);
				 */
	  			
	  			localObj2ProjMap.put(words[0].trim(), projName);
	  			//System.out.println(words[0].trim() + " : " + path2ProjMap.get(dir));
	  		}
			
	  		/*
	  		else
	  		{
	  			
	  			
	  			if ((dir == null) || (dir.indexOf('/') < 0))
	  			{
	  				//System.out.println(words[9]);
	  				ss++;
	  				continue;
	  			}
	  			
	  			//concernSet.add(words[5]);
	  			//if (dir.substring(0, dir.indexOf('/')).equals("out") 
	  					//|| dir.substring(0, dir.indexOf('/')).equals("target"))
	  			if (!Utilities.folderList.contains(dir.substring(0, dir.indexOf('/'))))
	  			{
	  				//System.out.println(dir);
	  				tt++;
	  			}
	  			else
	  			{
	  				System.out.println(words[0] + " : " + " : " + dir + " : " + words[1]);
	  			}
	  			
	  			//System.out.println(words[0].trim() + " : " + dir);
	  		}
	  		*/
	  		
	  	}
	  	
	  	for (String extension: (Set<String>)extensionSet.keySet())
	  	{
	  		System.out.println(extension + " : " + extensionSet.getCollection(extension).size());
	  	}
	  	
	  	//System.out.println(localObj2ProjMap.size() + " retrieved");
	  	
	  	Utilities.writeMapToFile(localObj2ProjMap, localObj2ProjMapFile);
	  	
	  	MultiHashMap obj2ObjMap = new MultiHashMap();
		while((line = inBuffer.readLine()) != null)
		{	
			String words[] = line.split(",");
			
  			String objName = words[0].trim();
  			
  			/*
  			int indexOfUnderscore = objName.indexOf('_');
  			indexOfUnderscore = indexOfUnderscore < 0 ? objName.length() : indexOfUnderscore;
  			
  			objName = objName.substring(0, indexOfUnderscore);
  			
  			
  			String obj2Name = words[1].trim();
  			
  			indexOfUnderscore = obj2Name.indexOf('_');
  			indexOfUnderscore = indexOfUnderscore < 0 ? obj2Name.length() : indexOfUnderscore;
  			
  			obj2Name = obj2Name.substring(0, indexOfUnderscore);
			
			obj2ObjMap.put(objName, obj2Name);
			*/
  			
  			obj2ObjMap.put(words[0].trim(), words[1].trim());
		}
		Utilities.writeMultiMapToFile(obj2ObjMap, obj2ObjMapFile);
		
		//System.out.println(obj2ObjMap.totalSize());
	  	
		inBuffer.close();
		
	  	//System.out.println(localObj2ProjMap.size());
	  	
	  	//System.out.println(tt);
	  	
	  	//System.out.println(ss);
	  	
	  	//System.out.println(Utilities.truncat(5, "/home/dan/bin/working_directory/").length());
	  	
	  	//System.out.println(concernSet.size());
	  	/*
	  	Iterator it =  concernSet.iterator();
	  	while(it.hasNext())
	  	{
	  		System.out.println(it.next());
	  	}
	  	*/
		/*
		HashMap<String, String> globalObj2ProjTmpMap = new HashMap<String, String>();
	  	
	  	HashSet<String> globalObjSet = new HashSet<String>();
	  	
	  	HashSet<String> dupGlobalObjSet = new HashSet<String>();
	  	
	  	HashSet<String> basedOnGlobalObjSet = new HashSet<String>();
	  	
	  	int ll = 0;
	  	
		while((line = inBuffer.readLine()) != null)
		{
			String words[] = line.split(",");
			
			//bypass the local obj
			if (localObjSet.contains(words[0]))
			{
				continue;
			}
			
			//bypass the duplicated global variable
			if (dupGlobalObjSet.contains(words[0]))
			{
				continue;
			}
			
			if (basedOnGlobalObjSet.contains(words[0]))
			{
				continue;
			}
			
			if (!globalObjSet.contains(words[0]))
			{
				if (!localObjSet.contains(words[1]))
				{
					basedOnGlobalObjSet.add(words[0]);
					
					continue;
				}
				
				globalObjSet.add(words[0]);
				
				globalObj2ProjTmpMap.put(words[0], localObj2ProjMap.get(words[1]));
				
				continue;
			}
			else
			{
				if (!localObjSet.contains(words[1]))
				{
					basedOnGlobalObjSet.add(words[0]);
					
					globalObjSet.remove(words[0]);
					globalObj2ProjTmpMap.remove(words[0]);
					
					ll++;
					
					continue;
				}
				
				if (!globalObj2ProjTmpMap.get(words[0]).equals(localObj2ProjMap.get(words[1])))
				{
					dupGlobalObjSet.add(words[0]);
					
					globalObjSet.remove(words[0]);
					globalObj2ProjTmpMap.remove(words[0]);
					
					continue;
				}
			}	
		}
		
		System.out.println(globalObj2ProjTmpMap.size());
		System.out.println(dupGlobalObjSet.size());
		System.out.println(globalObjSet.size());
		System.out.println(basedOnGlobalObjSet.size());
		*/
	}
	
	public static void main(String args[]) throws IOException
	{
		ParseGdf fuyun = new ParseGdf();
		
		fuyun.getObj2ProjMap("data/android-4.0.1/projPath2NameMap.csv", 
				"data/android-4.0.1/all.gdf", 
				"data/android-4.0.1/localObj2ProjMap.csv", 
				"data/android-4.0.1/obj2ObjMap.csv");
	}
}
